//
//  HKTools.swift
//  HKUtilitySwift
//
//  Created by 胡锦涛 on 2018/12/21.
//  Copyright © 2018 胡锦涛. All rights reserved.
//

import UIKit
import Foundation
import MediaPlayer

extension Int{
    var scale : Int{
        return Int(ceil(Double(self)*HKSwiftMacro.scale))
    }
}

extension CGRect{
    
    static public func scale(_ scaleX: Int,_ scaleY: Int,_ scaleW: Int,_ scaleH: Int) -> CGRect{
        return CGRect(x: scaleX.scale, y: scaleY.scale, width: scaleW.scale, height: scaleH.scale)
    }
    
}

extension String {
    
    /// 获取字符串长度
    var length: Int {
        return self.count
    }
    
    ///过滤空格
    public var noSpaceString: String{
        let s = self as NSString
        return s.replacingOccurrences(of:" ", with: "") as String
    }
    
    ///手机号加密显示
    public func safeMdn() -> String{
        var resultMdn:String = ""
        if !self.isEmpty {
            let phoneStr:NSMutableString = NSMutableString(string: self)
            let tempRange:NSRange = NSMakeRange(3, 4)
            phoneStr.replaceCharacters(in: tempRange, with: "****")
            resultMdn = "\(phoneStr)"
        }else {
            resultMdn = ""
        }
        return resultMdn
    }
    
    ///获取字符串不为空的值
    public func value() -> String {
        if self.isEmpty {
            return ""
        }else {
            return self
        }
    }
    
    var hk_IsMobile: Bool {
        let mobile = "^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|7[06-8])\\d{8}$"
        let predicate = NSPredicate.init(format: "SELF MATCHES %@", mobile)
        return predicate.evaluate(with: self)
    }
    
    ///是否包含中文
    public func isIncludeChinese() -> Bool {
        for (_, value) in self.enumerated() {
            if ("\u{4E00}" <= value  && value <= "\u{9FA5}") {
                return true
            }
        }
        return false
    }
    
    public func contains(substr: String) -> Bool {
        return self.range(of: substr) != nil
    }
    
    public func componentsSeparated(_ componentsSeparat:String) -> [String:Any]{
        
        let a = components(separatedBy: componentsSeparat)
        var dict = [String:Any]()
        for s in a {
            
            let str = s.hk_urlDecoded() as NSString
            
            if str.contains("="){
                let range = str.range(of: "=")
                let key = str.substring(to: range.location)
                let value = str.substring(from: range.location+1)
                dict[key] = value
            }
        }
        return dict
    }
    
    /// 获取富文本字符串
    func attributeString(color: UIColor, font: UIFont) -> NSAttributedString {
        let attributesDic = [NSAttributedString.Key.foregroundColor: color, NSAttributedString.Key.font: font]
        return NSAttributedString.init(string: self, attributes: attributesDic)
    }
    
    ///文本添加行间距
    public func add(lineSpacing:CGFloat, withFontSize fontSize:CGFloat) -> NSAttributedString{
        let paraph = NSMutableParagraphStyle()
        paraph.lineSpacing = lineSpacing
        let attributes = [NSAttributedString.Key.font:UIFont.systemFont(ofSize: fontSize),
                          NSAttributedString.Key.paragraphStyle : paraph]
        
        return NSAttributedString(string: self, attributes: attributes)
    }
    
    /// 计算文本高度
    func textHeight(font: UIFont, maxWidth: CGFloat = CGFloat.greatestFiniteMagnitude) -> CGFloat {
        let lable = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: maxWidth, height: 0))
        lable.font = font
        lable.text = self
        lable.numberOfLines = 0
        return lable.sizeThatFits(CGSize.init(width: maxWidth, height: CGFloat.greatestFiniteMagnitude)).height
    }
    
    /// 计算文本宽度
    func textWidth(font: UIFont) -> CGFloat {
        let lable = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: CGFloat.greatestFiniteMagnitude, height: 0))
        lable.font = font
        lable.text = self
        lable.numberOfLines = 0
        return lable.sizeThatFits(CGSize.init(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)).width
    }
    
    public var jsonDictionary: Any?{
        
        let jsonData:Data = self.data(using: .utf8)!
        let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
        if dict != nil {
            return dict
        }
        HKLog("字符串josn解析失败")
        return nil
    }
}
extension String {
    
    //将原始的url编码为合法的url
    func hk_urlEncoded() -> String {
        let encodeUrlString = self.addingPercentEncoding(withAllowedCharacters:
            .urlQueryAllowed)
        return encodeUrlString ?? ""
    }
    
    //将编码后的url转换回原始的url
    func hk_urlDecoded() -> String {
        return self.removingPercentEncoding ?? ""
    }
}

// MARK: - 类似GCD 的延时执行
extension DispatchTime: ExpressibleByIntegerLiteral {
    
    public init(integerLiteral value: Int) {
        self = DispatchTime.now() + .seconds(value)
    }
    
    public init(floatLiteral value: Double) {
        self = DispatchTime.now() + .milliseconds(Int(value * 1000))
    }
    
}

// MARK: - UI控件扩展
extension UILabel {
    
    convenience init(_ font: UIFont = UIFont.systemFont(ofSize: 14), textColor: UIColor = UIColor.black, text: String = "", textAlignment: NSTextAlignment = .left, superView: UIView?) {
        self.init()
        self.font = font
        self.textColor = textColor
        self.text = text
        self.textAlignment = textAlignment
        if superView != nil {
            superView!.addSubview(self)
        }
    }
    
    public func set(attriText:String?,lineSpacing:CGFloat = 2) {
        
        guard let text = attriText  else { return  }
        let paraph = NSMutableParagraphStyle()
        paraph.lineSpacing = lineSpacing
        let attributes = [NSAttributedString.Key.font:font,
                          NSAttributedString.Key.paragraphStyle : paraph] as [NSAttributedString.Key : Any]
        attributedText = NSAttributedString(string: text, attributes: attributes)
    }
}
// MARK: - UIImageView控件扩展
extension UIImageView{
    
    //添加自旋转动画
    func hk_addRotateAni(_ duration:Float = 4) {
        
        if self.layer.animation(forKey: "transform.rotation.z") == nil{
            let rotationAnimation:CABasicAnimation = CABasicAnimation.init()
            rotationAnimation.toValue = NSNumber.init(value: (2 * Double.pi))
            rotationAnimation.duration = CFTimeInterval(duration)
            rotationAnimation.repeatCount = MAXFLOAT
            rotationAnimation.isRemovedOnCompletion = false
            self.layer.add(rotationAnimation, forKey: "transform.rotation.z")
        }
        
    }
    
}
// MARK: - UIButton控件扩展
extension UIButton {
    
    // convenience : 便利,使用convenience修饰的构造函数叫做便利构造函数
    // 遍历构造函数通常用在对系统的类进行构造函数的扩充时使用
    /*
     便利构造函数的特点
     1.遍历构造函数通常都是写在extension里面
     2.遍历构造函数init前面需要加载convenience
     3.在遍历构造函数中需要明确的调用self.init()
     */
    convenience init (imageName : String, bgImageName : String) {
        self.init()
        setImage(UIImage(named: imageName), for: .normal)
        setImage(UIImage(named: imageName + "_highlighted"), for: .highlighted)
        setBackgroundImage(UIImage(named: bgImageName), for: .normal)
        setBackgroundImage(UIImage(named: bgImageName + "_highlighted"), for: .highlighted)
        sizeToFit()
    }
    
    convenience init(bgColor : UIColor, fontSize : CGFloat, title : String) {
        self.init()
        
        setTitle(title, for: .normal)
        backgroundColor = bgColor
        titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
    }
    
    convenience init(titleFont: UIFont = UIFont.systemFont(ofSize: 14), normalTitleColor: UIColor = UIColor.black, normalTitle: String = "", target: Any?, action: Selector, superView: UIView?) {
        self.init(type: .custom)
        self.titleLabel?.font = titleFont
        self.setTitleColor(normalTitleColor, for: .normal)
        self.setTitle(normalTitle, for: .normal)
        self.addTarget(target, action: action, for: .touchUpInside)
        if superView != nil {
            superView!.addSubview(self)
        }
    }
    
    convenience init(normalImage: UIImage, target: Any?, action: Selector, superView: UIView?) {
        self.init(type: .custom)
        self.setImage(normalImage, for: .normal)
        self.addTarget(target, action: action, for: .touchUpInside)
        if superView != nil {
            superView!.addSubview(self)
        }
    }
    
    func hk_layOutWith(title: String, position: UIView.ContentMode,
                                     spacing: CGFloat) {
        let imageSize = self.imageRect(forContentRect: self.frame)
        let titleFont = self.titleLabel?.font!
        let titleSize = title.size(withAttributes: [NSAttributedString.Key.font: titleFont!])
        
        var titleInsets: UIEdgeInsets
        var imageInsets: UIEdgeInsets
        
        switch (position){
        case .top:
            titleInsets = UIEdgeInsets(top: -(imageSize.height + titleSize.height + spacing),
                                       left: -(imageSize.width), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -titleSize.width)
        case .bottom:
            titleInsets = UIEdgeInsets(top: (imageSize.height + titleSize.height + spacing),
                                       left: -(imageSize.width), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -titleSize.width)
        case .left:
            titleInsets = UIEdgeInsets(top: 0, left: -(imageSize.width * 2), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0,
                                       right: -(titleSize.width * 2 + spacing))
        case .right:
            titleInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -spacing)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        default:
            titleInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        }
        
        self.titleEdgeInsets = titleInsets
        self.imageEdgeInsets = imageInsets
    }
}
// MARK: - UIImage控件扩展
extension UIImage {
    
    ///始终保持图片原有的状态，不使用Tint Color渲染
    static func noRenderingImageName(imageName:String) -> UIImage {
        let image : UIImage = ((UIImage(named:imageName)?.withRenderingMode(.alwaysOriginal)))!
        /**
         UIImageRenderingModeAutomatic  自动根据当前环境渲染
         UIImageRenderingModeAlwaysOriginal  使用原有的图片状态，不被Tint Color所渲染
         UIImageRenderingModeAlwaysTemplate  渲染图片
         */
        return image
    }
    
    ///获取纯色图片
    static func createImage(_ color:UIColor) -> UIImage {
        
        let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        context?.fill(rect)
        let theImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return theImage!
    }
    
    ///修正图片方向
    func fixedOrientation() -> UIImage {
        
        if imageOrientation == .up {
            return self
        }
        
        var transform: CGAffineTransform = CGAffineTransform.identity
        
        switch imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: size.height)
            transform = transform.rotated(by: .pi)
            break
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: size.width, y: 0)
            transform = transform.rotated(by: .pi/2)
            break
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: size.height)
            transform = transform.rotated(by: -.pi/2)
            break
        case .up, .upMirrored:
            break
        }
        
        switch imageOrientation {
        case .upMirrored, .downMirrored:
            transform.translatedBy(x: size.width, y: 0)
            transform.scaledBy(x: -1, y: 1)
            break
        case .leftMirrored, .rightMirrored:
            transform.translatedBy(x: size.height, y: 0)
            transform.scaledBy(x: -1, y: 1)
        case .up, .down, .left, .right:
            break
        }
        
        let ctx: CGContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: (self.cgImage?.colorSpace)!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
        
        ctx.concatenate(transform)
        
        switch imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
            break
        default:
            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            break
        }
        
        let cgImage: CGImage = ctx.makeImage()!
        
        return UIImage(cgImage: cgImage)
    }
}

// MARK: - UITextField控件扩展
extension UITextField {
    
    convenience init(_ font: UIFont = UIFont.systemFont(ofSize: 14), textColor: UIColor = UIColor.black, textAlignment: NSTextAlignment = .left, clearButtonMode: UITextField.ViewMode = .whileEditing, placeholder: String = "", superView: UIView?) {
        
        self.init()
        self.font = font
        self.textColor = textColor
        self.textAlignment = textAlignment
        self.clearButtonMode = clearButtonMode
        self.placeholder = placeholder
        if superView != nil {
            superView?.addSubview(self)
        }
    }
    
    /// 为textfield添加键盘上部完成按钮
    func addDoneButtonForKeyboard() {
        let bar = UIToolbar(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: 44))
        let spaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let item = UIBarButtonItem(title: "完成", style: .plain, target: self, action: #selector(shouldEndEditing))
        bar.items = [spaceItem,item]
        inputAccessoryView = bar
    }
    
    @objc private func shouldEndEditing() {
        endEditing(true)
    }
}

//MARK:UIBarButtonItem-扩展
extension UIBarButtonItem {
    
    convenience init(imageName : String) {
        
        let btn = UIButton()
        btn.setImage(UIImage(named: imageName), for: .normal)
        btn.setImage(UIImage(named: imageName + "_highlighted"), for: .highlighted)
        btn.sizeToFit()
        self.init(customView : btn)
    }
}

//MARK:UIColor-扩展
extension UIColor {
    
    ///返回随机颜色 2017.11.25
    open class var random:UIColor{
        get
        {
            let red = CGFloat(arc4random()%256)/255.0
            let green = CGFloat(arc4random()%256)/255.0
            let blue = CGFloat(arc4random()%256)/255.0
            return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
        }
    }
}
//MARK: Date-扩展
extension Date {
    func transformToString(_ format:String) -> String {
        let dateFormatter = DateFormatter.init()
        dateFormatter.dateFormat = format.isEmpty ? "yyyy-MM" : format
        return dateFormatter.string(from: self as Date)
    }
}

extension Date {
    var age: Int {
        return NSCalendar.current.dateComponents([.year,.month], from: self, to: Date()).year ?? 0
    }
}

extension NSDate {
    class func createDateString(createAtStr : String) -> String {
        // 1.创建时间格式化对象
        let fmt = DateFormatter()
        fmt.dateFormat = "EEE MM dd HH:mm:ss Z yyyy"
        fmt.locale = NSLocale(localeIdentifier: "en") as Locale
        
        // 2.将字符串时间,转成NSDate类型
        guard let createDate = fmt.date(from: createAtStr) else {
            return ""
        }
        
        // 3.创建当前时间
        let nowDate = NSDate()
        
        // 4.计算创建时间和当前时间的时间差
        let interval = Int(nowDate.timeIntervalSince(createDate))
        
        // 5.对时间间隔处理
        // 5.1.显示刚刚
        if interval < 60 {
            return "刚刚"
        }
        
        // 5.2.59分钟前
        if interval < 60 * 60 {
            return "\(interval / 60)分钟前"
        }
        
        // 5.3.11小时前
        if interval < 60 * 60 * 24 {
            return "\(interval / (60 * 60))小时前"
        }
        
        // 5.4.创建日历对象
        let calendar = NSCalendar.current
        
        // 5.5.处理昨天数据: 昨天 12:23
        if calendar.isDateInYesterday(createDate) {
            fmt.dateFormat = "昨天 HH:mm"
            let timeStr = fmt.string(from: createDate)
            return timeStr
        }
        
        // 5.6.处理一年之内: 02-22 12:22
        let cmps = calendar.component(.year, from: createDate)//calendar.components(.Year, fromDate: createDate, toDate: nowDate, options: [])
        if cmps < 1 {
            fmt.dateFormat = "MM-dd HH:mm"
            let timeStr = fmt.string(from: createDate)
            return timeStr
        }
        
        // 5.7.超过一年: 2014-02-12 13:22
        fmt.dateFormat = "yyyy-MM-dd HH:mm"
        let timeStr = fmt.string(from: createDate)
        return timeStr
    }
}
//MARK:UIViewController-扩展
extension UIViewController {
    
    public func hk_hidenNavBar(_ animated: Bool) {
        navigationController?.setNavigationBarHidden(true, animated: animated)
        navigationController?.navigationBar.setValue(0, forKeyPath: "backgroundView.alpha")
    }
    
    public func hk_showNavBar(_ animated: Bool) {
        navigationController?.setNavigationBarHidden(false, animated: animated)
        navigationController?.navigationBar.setValue(1, forKeyPath: "backgroundView.alpha")
    }
    
    public func hk_hidenTabBar() {
        let tabBarController = UIApplication.shared.delegate?.window??.rootViewController as! UITabBarController
        //        tabBarController.tabBar.isHidden = true
        let frame = tabBarController.tabBar.frame
        let height = frame.size.height
        UIView.animate(withDuration: 0.35, animations: {
            tabBarController.tabBar.frame = (frame.offsetBy(dx: 0, dy: height))
        }) { (finished) in
            tabBarController.tabBar.isHidden = true
        }
    }
    
    public func hk_showTabBar() {
        let tabBarController = UIApplication.shared.delegate?.window??.rootViewController as! UITabBarController
        tabBarController.tabBar.isHidden = false
        let frame = tabBarController.tabBar.frame
        UIView.animate(withDuration: 0.35, animations: {
            tabBarController.tabBar.frame = (frame.offsetBy(dx: 0, dy: 0))
        }){ (finished) in
            
        }
    }
    
    @objc public func hk_back() {
        if let navigationController = navigationController, navigationController.viewControllers.first != self {
            navigationController.popViewController(animated: true)
        } else {
            dismiss(animated: true, completion: nil)
        }
    }
    
    func hk_addChildViewController(_ childVC: UIViewController, toView: UIView) {
        childVC.beginAppearanceTransition(true, animated: false)
        toView.addSubview(childVC.view)
        childVC.endAppearanceTransition()
        childVC.didMove(toParent: self)
    }
    
    // MARK: 字典转字符串
    func hk_dicValueString(_ dic: Any) -> String?{
        let data = try? JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted)
        let str = String(data: data!, encoding: String.Encoding.utf8)
        return str
    }
    
    // MARK: 字符串转字典
    func hk_infoFromJson(_ str: String) -> HKDefaultDic?{
        guard !str.isEmpty else {
            return HKDefaultDic()
        }
        let data = str.data(using: String.Encoding.utf8)
        if let array = try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? [HKDefaultDic] {
            return array!.first
        }
        return nil
    }
}

extension UIDevice{
    
    func blankof<T>(type:T.Type) -> T {
        let ptr = UnsafeMutablePointer<T>.allocate(capacity: MemoryLayout<T>.size)
        let val = ptr.pointee
        ptr.deinitialize(count: 1)
        return val
    }
    
    /// 磁盘总大小
    var TotalDiskSize:Int64{
        var fs = blankof(type: statfs.self)
        if statfs("/var",&fs) >= 0{
            return Int64(UInt64(fs.f_bsize) * fs.f_blocks)
        }
        return -1
    }
    
    /// 磁盘可用大小
    var AvailableDiskSize:Int64{
        var fs = blankof(type: statfs.self)
        if statfs("/var",&fs) >= 0{
            return Int64(UInt64(fs.f_bsize) * fs.f_bavail)
        }
        return -1
    }
    
    /// 将大小转换成字符串用以显示
    func fileSizeToString(fileSize:Int64) -> String{
        
        let fileSize1 = CGFloat(fileSize)
        
        let KB:CGFloat = 1024
        let MB:CGFloat = KB*KB
        let GB:CGFloat = MB*KB
        
        return String(format: "%.1f GB", CGFloat(fileSize1)/GB)
        
        //        if fileSize < 10
        //        {
        //            return "0 B"
        //        }else if fileSize1 < KB
        //        {
        //            return "< 1 KB"
        //        }else if fileSize1 < MB
        //        {
        //            return String(format: "%.1f KB", CGFloat(fileSize1)/KB)
        //        }else if fileSize1 < GB
        //        {
        //            return String(format: "%.1f MB", CGFloat(fileSize1)/MB)
        //        }else
        //        {
        //            return String(format: "%.1f GB", CGFloat(fileSize1)/GB)
        //        }
    }
}

/// swift 延时进行封装 使用方法 delay(time){// DOSOMETHING}
extension NSObject {
    
    /*
     使用例子 全局队列
     delay(by: 5, qosClass: .userInitiated) {
     print("时间2：", Date())
     }
     */
    public func hk_delay(by delayTime: TimeInterval, qosClass: DispatchQoS.QoSClass? = nil,
                      _ closure: @escaping () -> Void) {
        let dispatchQueue = qosClass != nil ? DispatchQueue.global(qos: qosClass!) : .main

        dispatchQueue.asyncAfter(
            deadline: DispatchTime.now() + delayTime, execute: closure
        )
    }
    
    ///[使用运行时]获取当前类所有的属性数组
    public func propertyList() -> [String] {
        var properties:[String] = [String]()
        var count :UInt32 = 0
        //获取‘类’的属性列表
        let list = class_copyPropertyList(self.classForCoder, &count)
        print("属性的数量\(count)")
        for i in 0..<Int(count) {
            //根据下标 获取属性
            let a = list?[i]
            //获取属性的名称
            let cName = property_getName(a!)
            let n:String = String(utf8String:cName) ?? ""
            properties.append(n)
            print("\(n)\n")
        }
        return properties;
    }
    
}
// MARK: - Array-扩展
extension Array{
    
    public var jsonString: String{
        
        if (!JSONSerialization.isValidJSONObject(self)) {
            HKLog("无法解析出JSONString")
            return ""
        }
        let data : Data = try! JSONSerialization.data(withJSONObject: self, options: [])
        let JSONString = String(data: data, encoding: String.Encoding.utf8)
        return JSONString!
    }
    
    
    
    
}
// MARK: - Dictionary-扩展
extension Dictionary {
    
    public var jsonString: String{
        
        if (!JSONSerialization.isValidJSONObject(self)) {
            HKLog("无法解析出JSONString")
            return ""
        }
        let data : Data = try! JSONSerialization.data(withJSONObject: self, options: [])
        let JSONString = String(data: data, encoding: String.Encoding.utf8)
        return JSONString!
    }
    
    /// 获取字典中的字符串value
    func stringValue(key: Key, defaultValue: String = "") -> String {
        
        let value = self[key]
        switch value {
        case let string as String:
            return string.count > 0 ? string : defaultValue
        case let number as NSNumber:
            return number.stringValue
        default:
            return defaultValue
        }
    }
    
    /// 获取字典中的整形value
    func intValue(key: Key, defaultValue: Int = 0) -> Int {
        
        let value = self[key]
        switch value {
        case let value as Int:
            return value
        case let value as String:
            return atol(value)
        case let value as NSNumber:
            return value.intValue
        default:
            return defaultValue
        }
    }
    
    /// 获取字典中的单精度浮点型value
    func floatValue(key: Key, defaultVale: Float = 0.0) -> Float {
        let value = self[key]
        switch value {
        case let value as Float:
            return value
        case let value as NSNumber:
            return value.floatValue
        default:
            return defaultVale
        }
    }
    
    /// 获取字典中的双精度浮点型value
    func doubleValue(key: Key, defaultVale: Double = 0.0) -> Double {
        let value = self[key]
        switch value {
        case let value as Double:
            return value
        case let value as String:
            return atof(value)
        case let value as NSNumber:
            return value.doubleValue
        default:
            return defaultVale
        }
    }
    
    /// 获取字典中的bool型value
    func boolValue(key: Key, defaultValue: Bool = false) -> Bool {
        let value = self[key]
        switch value {
        case let value as Bool:
            return value
        case let value as NSNumber:
            return value.boolValue
        default:
            return defaultValue
        }
    }
}
//MARK: UIView扩展-frame
extension UIView {
    
    /// X
    public var hk_left: CGFloat{
        get{
            return self.frame.origin.x
        }
        set{
            var r = self.frame
            r.origin.x = newValue
            self.frame = r
        }
    }
    
    /// Y
    public var hk_top: CGFloat{
        get{
            return self.frame.origin.y
        }
        set{
            var r = self.frame
            r.origin.y = newValue
            self.frame = r
        }
    }
    
    /// 右边界的X值
    public var hk_right: CGFloat{
        get{
            return self.hk_left + self.hk_width
        }
        set{
            var r = self.frame
            r.origin.x = newValue - frame.size.width
            self.frame = r
        }
    }
    
    /// 下边界的Y值
    public var hk_bottom: CGFloat{
        get{
            return self.hk_top + self.hk_height
        }
        set{
            var r = self.frame
            r.origin.y = newValue - frame.size.height
            self.frame = r
        }
    }
    
    /// centerX
    public var hk_centerX : CGFloat{
        get{
            return self.center.x
        }
        set{
            self.center = CGPoint(x: newValue, y: self.center.y)
        }
    }
    
    /// centerY
    public var hk_centerY : CGFloat{
        get{
            return self.center.y
        }
        set{
            self.center = CGPoint(x: self.center.x, y: newValue)
        }
    }
    
    /// width
    public var hk_width: CGFloat{
        get{
            return self.frame.size.width
        }
        set{
            var r = self.frame
            r.size.width = newValue
            self.frame = r
        }
    }
    /// height
    public var hk_height: CGFloat{
        get{
            return self.frame.size.height
        }
        set{
            var r = self.frame
            r.size.height = newValue
            self.frame = r
        }
    }
    
    /// origin
    public var origin: CGPoint{
        get{
            return self.frame.origin
        }
        set{
            self.hk_left = newValue.x
            self.hk_top = newValue.y
        }
    }
    
    /// size
    public var size: CGSize{
        get{
            return self.frame.size
        }
        set{
            self.hk_width = newValue.width
            self.hk_height = newValue.height
        }
    }
    
}
//MARK:UIView圆角属性
extension UIView {
    
    func roundCorner () {
        self.layer.cornerRadius = self.hk_height/2;
        self.layer.masksToBounds = true
    }
    
    func hk_addBorder(_ bColor:UIColor, _ bWidth:CGFloat) {
        self.layer.borderColor = bColor.cgColor
        self.layer.borderWidth = bWidth
    }
}

@objc protocol HKNotiProtocol : NSObjectProtocol {
    @objc func loginCompleted()
    @objc func paySuccess()
}

class HKNotification: NSObject {
    
    struct Name {}
    
    static func postLoginNoti(){
        self.post(name: HKNotification.Name.LoginCompleted, object: nil)
    }
    
    static func postPaySuccessNoti(){
        self.post(name: HKNotification.Name.ThirdPaySuccess, object: nil)
    }
    
    static func postHistoryChangeNoti(){
        self.post(name: HKNotification.Name.HistoryChange, object: nil)
    }
    
    static func postNetStatusChangeNoti(){
        self.post(name: HKNotification.Name.NetStatusChange, object: nil)
    }
    
    static func addLoginNoti(_ observer: HKNotiProtocol){
        NotificationCenter.default.addObserver(observer, selector: #selector(observer.loginCompleted), name: HKNotification.Name.LoginCompleted, object: nil)
    }
    
    static func addPaySuccessNoti(_ observer: HKNotiProtocol){
        NotificationCenter.default.addObserver(observer, selector: #selector(observer.paySuccess), name: HKNotification.Name.ThirdPaySuccess, object: nil)
    }
    
}
//HKNotification.post(name: HKNotification.Name.ShareCompleted, object: ["isSuccess":false])
extension HKNotification.Name{
    
    public static let ThirdPaySuccess = notiName("ThirdPaySuccess")
    public static let LoginCompleted = notiName("LoginCompleted")
    public static let HistoryChange = notiName("HistoryChange")
    public static let ShareCompleted = notiName("ShareCompleted")
    public static let UserInfoDidChange = notiName("UserInfoDidChange")
    public static let GetAPIHostSuccess = notiName("GetAPIHostSuccess")
    public static let MyCollectDidChange = notiName("MyCollectDidChange")
    public static let InviteSuccess = notiName("InviteSuccess")
    public static let SrartMorelink = notiName("SrartMorelink")
    public static let EndFreeTrial = notiName("EndFreeTrial") //结束免费试看 视频播放结束免费看
    public static let GetPayResult = notiName("GetPayResult") //支付时点击左上角返回按钮触发，向服务器获取支付结果
    public static let CacheSizeChange = notiName("CacheSizeChange")
    public static let NetStatusChange = notiName("NetStatusChange")
    public static let APPISINSTART = notiName("APPISINSTART")
    public static let DotRefresh = notiName("DotRefresh")
    
    public static let VideoPlayDidEnd = notiName(NSNotification.Name.AVPlayerItemDidPlayToEndTime.rawValue)

    static func notiName(_ name:String) -> NSNotification.Name{
        return NSNotification.Name(rawValue: name)
    }
}


extension HKNotification{
    
    static func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?){
        NotificationCenter.default.addObserver(observer, selector: aSelector, name: aName, object: anObject)
    }
    
    static func post(name aName: NSNotification.Name, object anObject: Any?){
        NotificationCenter.default.post(name: aName, object: anObject)
    }
    
    static func post(name aName: NSNotification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable : Any]? = nil){
        NotificationCenter.default.post(name: aName, object: anObject, userInfo: aUserInfo)
    }
    
    static func removeObserver(_ observer: Any){
        NotificationCenter.default.removeObserver(observer)
    }
    
    static func removeObserver(_ observer: Any, name aName: NSNotification.Name?, object anObject: Any?){
        NotificationCenter.default.removeObserver(observer, name: aName, object: anObject)
    }
    
    @discardableResult static func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Swift.Void) -> NSObjectProtocol{
        return NotificationCenter.default.addObserver(forName: name, object: obj, queue: queue, using: block)
    }
    
}
